/**
 * Copyright 2016-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.inmorn.redisclient.redis.jedis;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javassist.ClassMap;
import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.CycleDetectionStrategy;
import net.sf.json.util.JSONUtils;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import redis.clients.jedis.BinaryClient.LIST_POSITION;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.Response;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPipeline;

import com.inmorn.redisclient.JsonDateValueProcessor;
import com.inmorn.redisclient.RedisAspect;
import com.inmorn.redisclient.redis.IRedisClient;

/**
 * 
 * 
 */
public class RedisClientTemplate implements IRedisClient{
	private Log logger = LogFactory.getLog(getClass());
	public ShardedJedis getCurShardedJedis(){
		return RedisAspect.getCurShardedJedis();
	}
	public ShardedJedis getCurShardedJedisOther(){
		return RedisAspect.getCurShardedJedisOther();
	}
	
	public List<?> getListTrim(String listKey,int number,Class<?> clazz){
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in listKey current server is:["
				+ shardedJedis.getShard(listKey).getClient().getHost() + "]");
		ShardedJedisPipeline shardedJedisPipeline = shardedJedis.pipelined();
		Response<List<String>> responses = 
				shardedJedisPipeline.lrange(listKey, 0, number-1);
		shardedJedisPipeline.ltrim(listKey, number, -1);
		shardedJedisPipeline.sync();
		if(responses != null){
			List<String> list = responses.get();
			return com.alibaba.fastjson.JSONObject
					.parseArray(list.toString(), clazz);
		}
		return null;
	}

	/**
	 * 插入单一string
	 * 
	 * @param key
	 * @param value
	 * @return null表示失败
	 */
	public String setSingleString(String key, String value) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in setSingleString current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in setSingleString current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
//		value = value.substring(1, value.length()-1);
		String res = shardedJedis.set(key, value);
		return res;
	}

	/**
	 * 如果不存在这个key，则插入string，否则不做任何操作
	 * 
	 * @param key
	 * @param value
	 * @return 1 插入成功 0没有插入
	 */
	public Long setNewString(String key, String value) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in setNewString current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in setNewString current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		Long res = shardedJedis.setnx(key, value);
		return res;
	}

	/**
	 * 在现有string基础上增加
	 * 
	 * @param key
	 * @param value
	 * @return null表示失败
	 */
	public Long appendSingleString(String key, String value) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in appendSingleString current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in appendSingleString current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		Long res = shardedJedis.append(key, value);
		return res;
	}

	/**
	 * 从起始范围插入string
	 * 
	 * @param key
	 * @param beginIndex
	 * @param value
	 * @return
	 */
	public Long setRangeString(String key, long beginIndex, String value) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in setRangeString current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in setRangeString current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		Long res = shardedJedis.setrange(key, beginIndex, value);
		return res;
	}

	/**
	 * 将String插入到已经存在的list
	 * 
	 * @param key
	 * @param value
	 * @param where
	 *            0放到第一位 1放到最后一位
	 * @return
	 */
	public Long setStringToExistList(String key, String value, long where) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in setStringToExistList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in setStringToExistList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		if (0 == where) {
			Long res = shardedJedis.lpushx(key, value);
			return res;
		} else {
			Long res = shardedJedis.rpushx(key, value);
			return res;
		}
	}
	
	/**
	 * 将对象插入到已经存在的list，暂不支持中文key（可能会有编码问题）
	 * 
	 * @param key
	 * @param obj
	 * @param where 0放到第一位 1放到最后一位
	 * @return
	 */
	public Long setObjectToExistList(String key, Object obj, long where) {
		if (null == obj)
			return null;
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in setObjectToExistList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in setObjectToExistList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		String json = this.converObjectToJason(obj);
		return this.setStringToExistList(key, json, where);
	}

	/**
	 * 将string放到list中
	 * 
	 * @param key
	 * @param value
	 * @param where
	 *            0放到第一位 1放到最后一位
	 * @return
	 */
	public Long setStringToList(String key, String value, long where) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in setStringToList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in setStringToList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		if (0 == where) {
			Long res = shardedJedis.lpush(key, value);
			return res;
		} else {
			Long res = shardedJedis.rpush(key, value);
			return res;
		}
	}

	
	/**
	 * 将对象插入到list，暂不支持中文key（可能会有编码问题）
	 * 
	 * @param key
	 * @param obj
	 * @param where 0放到第一位 1放到最后一位
	 * @return
	 */
	public Long setObjectToList(String key, Object obj, long where) {
		if (null == obj)
			return null;
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in setObjectToList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in setObjectToList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		String json = this.converObjectToJason(obj);
		return this.setStringToList(key, json, where);
	}

	/**
	 * 在list的index设置string
	 * 
	 * @param key
	 * @param index
	 * @param value
	 * @return
	 */
	public String setStringByIndexToList(String key, long index, String value) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in setStringByIndexToList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in setStringByIndexToList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		String res = shardedJedis.lset(key, index, value);
		return res;
	}
	
	/**
	 * 在list的index设置对象
	 * 
	 * @param key
	 * @param index
	 * @param obj
	 * @return
	 */
	public String setObjectByIndexToList(String key, int index, Object obj) {
		if (null == obj)
			return null;
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in setObjectByIndexToList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in setObjectByIndexToList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		String json = this.converObjectToJason(obj);
		return this.setStringByIndexToList(key, index, json);
	}

	/**
	 * 在一个list的string前/后插入一个string
	 * 
	 * @param key
	 * @param where 0前 1后
	 * @param pivot
	 * @param value
	 * @return
	 */
	public Long insertStringToList(String key, long where, String pivot,
			String value) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in insertStringToList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in insertStringToList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		if (where == 0) {
			Long res = shardedJedis.linsert(key, LIST_POSITION.BEFORE, pivot, value);
			return res;
		} else {
			Long res = shardedJedis.linsert(key, LIST_POSITION.AFTER, pivot, value);
			return res;
		}
	}
	
	/**
	 * 在一个list的object前/后插入一个object
	 * 
	 * @param key
	 * @param where 0前 1后
	 * @param pivot
	 * @param obj
	 * @return
	 */
	public Long insertObjectToList(String key, long where, String pivot,
			Object obj) {
		if (null == obj || null == pivot)
			return null;
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in insertObjectToList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in insertObjectToList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		String json = this.converObjectToJason(obj);
		return this.insertStringToList(key, where, pivot, json);
	}

	/**
	 * 从缓存获取单一string
	 * 
	 * @param key
	 * @return
	 */
	public String getSingleString(String key) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getSingleString current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getSingleString current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		return shardedJedis.get(key);
	}

	/**
	 * 获取缓存中的substring
	 * 
	 * @param key
	 * @param beginIndex
	 * @param endIndex
	 * @return
	 */
	public String getRangeString(String key, long beginIndex, long endIndex) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getRangeString current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getRangeString current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		return shardedJedis.getrange(key, beginIndex, endIndex);
	}

	/**
	 * 从list中获取一个范围的string
	 * 
	 * @param key
	 * @param beginIndex
	 * @param endIndex
	 * @return
	 */
	public List<String> getRangeStringFromList(String key, long beginIndex,
			long endIndex) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getRangeStringList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getRangeStringList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		return shardedJedis.lrange(key, beginIndex, endIndex);
	}

	/**
	 * 从list中获取一个范围的object
	 * 
	 * @param key
	 * @param beginIndex
	 * @param endIndex
	 * @return
	 */
	public List<?> getRangeObjectFromList(String key, int beginIndex,
			int endIndex, Class<?> clazz) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getRangeObjectFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getRangeObjectFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		List<String> listString = this.getRangeStringFromList(key, beginIndex, endIndex);
		if(listString == null || listString.size() == 0) 
			return null;
		else {
			JSONArray json = JSONArray.fromObject(listString);
			JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] { "yyyy-MM-dd HH:mm:ss" }));
			return (List<?>) JSONArray.toCollection(json, clazz);
		}
	}

	/**
	 * 从list中获取一个范围的object
	 * 
	 * @param key
	 * @param beginIndex
	 * @param endIndex
	 * @param jsonConfig
	 * @return
	 */
	public List<?> getRangeObjectFromList(String key, int beginIndex,
			int endIndex, Class<?> clazz, ClassMap classMap) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getRangeObjectFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getRangeObjectFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		List<String> listString = this.getRangeStringFromList(key, beginIndex, endIndex);
		if(listString == null || listString.size() == 0) 
			return null;
		else {
			List<Object> res = new ArrayList<Object>();
			for(String str : listString) {
				JSONObject jsonObject = JSONObject.fromObject(str);
				JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] { "yyyy-MM-dd HH:mm:ss" }));
				res.add(JSONObject.toBean(jsonObject, clazz, classMap));
			}
			
			return res;
		}
	}
	
	/**
	 * 获取整个string list
	 * @param key
	 * @return
	 */
	public List<String> getWholeStringList(String key) {
		return getRangeStringFromList(key, 0, -1);
	}

	/***
	 * 使用Pipeline获取队列key,value,并删除 Add xielongfei  2016.01.12
	 * @param listKey
	 * @param size
	 * @return
	 */
	public Map<String, Object> getValueAndRemoveKeys(String listKey, int size){
		//List<Object> list = new ArrayList<Object>();
		Map<String, Object> mapkey = new HashMap<String, Object>();
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("get shardedJedis from the pool ==============================:"+shardedJedis);
		//使用pipeline hgetall
		Map<String, Response<String>> mapval=new HashMap<String, Response<String>>();
		List<String> keys = shardedJedis.lrange(listKey, 0, size - 1);
		shardedJedis.ltrim(listKey, size, -1);
		//数据在最后删除,如丢失通过时间分片来恢复  shardedJedis.del(key);
		logger.debug("delete queue key ============================================");
		try {
			ShardedJedisPipeline shardedJedPipeline = shardedJedis.pipelined();
			for(String key : keys) {
				mapval.put(key, shardedJedPipeline.get(key));
			 }
			//管道同步,获取所有的response
			shardedJedPipeline.sync();
			
			for(String k : mapval.keySet()) {
				mapkey.put(k, mapval.get(k).get());
			    //list.add(mapval.get(k).get());
			}
		} catch (Exception e) {
			//如果获取散key的value失败,重新写入队列
			//shardedJedis.rpush(listKey, key);
			logger.error("管道获取value失败,暂时不处理redis异常数据......" + e);
		}
		return mapkey;
	}	
	
	/**
	 * 获取整个Object list
	 * @param key
	 * @return
	 */
	public List<?> getWholeObjectList(String key, Class<?> clazz) {
		return getRangeObjectFromList(key, 0, -1, clazz);
	}
	
	/**
	 * 获取整个Object list
	 * @param key
	 * @param clazz
	 * @param jsonConfig
	 * @return
	 */
	public List<?> getWholeObjectList(String key, Class<?> clazz, ClassMap classMap) {
		return getRangeObjectFromList(key, 0, -1, clazz, classMap);
	}

	/**
	 * 从list中获取并删除string
	 * @param key
	 * @param where 0 从头获取， 1从尾获取
	 * @return
	 */
	public String getAndRemoveStringFromList(String key, long where) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getAndRemoveStringFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getAndRemoveStringFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		if (0 == where)
			return shardedJedis.lpop(key);
		else
			return shardedJedis.rpop(key);
	}

	/**
	 * 从list中获取并删除对象
	 * @param key
	 * @param where 0 从头获取， 1从尾获取
	 * @return
	 */
	public Object getAndRemoveObjectFromList(String key, int where) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getAndRemoveObjectFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getAndRemoveObjectFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		JSONArray json = JSONArray.fromObject(this.getAndRemoveStringFromList(key, where));
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] { "yyyy-MM-dd HH:mm:ss" }));
		return JSONArray.toArray(json);
	}
	
	/**
	 * 从list中获取并删除对象
	 * @param key
	 * @param where 0 从头获取， 1从尾获取
	 * @return
	 */
	public Object getAndRemoveObjectFromList(String key, int where, Class<?> clazz) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getAndRemoveObjectFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getAndRemoveObjectFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		JSONArray json = JSONArray.fromObject(this.getAndRemoveStringFromList(key, where));
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] { "yyyy-MM-dd HH:mm:ss" }));
		return JSONArray.toArray(json, clazz);
	}
	
	/**
	 * 从list中获取并删除对象
	 * @param key
	 * @param where 0 从头获取， 1从尾获取
	 * @param classMap
	 * @return
	 */
	public Object getAndRemoveObjectFromList(String key, int where, Class<?> clazz, ClassMap classMap) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getAndRemoveObjectFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getAndRemoveObjectFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		JSONObject jsonObject = JSONObject.fromObject(this.getAndRemoveStringFromList(key, where));
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] { "yyyy-MM-dd HH:mm:ss" }));
		return JSONObject.toBean(jsonObject, clazz, classMap);
	}

	/**
	 * 根据index从list中获取string
	 * 
	 * @param key
	 * @param index
	 * @return
	 */
	public String getStringByIndexFromList(String key, long index) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getStringByIndexFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getStringByIndexFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		return shardedJedis.lindex(key, index);
	}
	
	
	/**
	 * 根据index从list中获取对象
	 * @param key
	 * @param index
	 * @return
	 */
	public Object getObjectByIndexFromList(String key, int index){
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getObjectByIndexFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getObjectByIndexFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		JSONArray json = JSONArray.fromObject(this.getStringByIndexFromList(key, index));
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] { "yyyy-MM-dd HH:mm:ss" }));
		return JSONArray.toArray(json);
	}
	
	/**
	 * 根据index从list中获取对象
	 * @param key
	 * @param index
	 * @param obj
	 * @return
	 */
	public Object getObjectByIndexFromList(String key, int index, Class<?> clazz){
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getObjectByIndexFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getObjectByIndexFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		JSONArray json = JSONArray.fromObject(this.getStringByIndexFromList(key, index));
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] { "yyyy-MM-dd HH:mm:ss" }));
		return JSONArray.toArray(json, clazz);
	}
	
	/**
	 * 根据index从list中获取对象
	 * @param key
	 * @param index
	 * @param obj
	 * @param classMap
	 * @return
	 */
	public Object getObjectByIndexFromList(String key, int index, Class<?> clazz, ClassMap classMap){
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getObjectByIndexFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getObjectByIndexFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		JSONObject jsonObject = JSONObject.fromObject(this.getStringByIndexFromList(key, index));
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] { "yyyy-MM-dd HH:mm:ss" }));
		return JSONObject.toBean(jsonObject, clazz, classMap);
	}

	/**
	 * 从List里面移除string
	 * 
	 * @param key
	 * @param count 移除次数
	 * @param value
	 * @return
	 */
	public Long remStringFromList(String key, long count, String value) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in remStringFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in remStringFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		return shardedJedis.lrem(key, count, value);
	}
	
	/**
	 * 从List里面移除object
	 * @param key
	 * @param count 移除次数
	 * @param obj
	 * @return
	 */
	public Long remObjectFromList(String key, int count, Object obj){
		if (null == obj)
			return null;
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in remObjectFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in remObjectFromList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setExcludes(new String[] { "" });
		jsonConfig.setIgnoreDefaultExcludes(false);
		jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
		jsonConfig.registerJsonValueProcessor(Date.class,        
				new JsonDateValueProcessor("yyyy-MM-dd HH:mm:ss"));
		
		String json = JSONArray.fromObject(obj, jsonConfig).toString();
		json = json.substring(1, json.length()-1);
		return this.remStringFromList(key, count, json);
	}

	/**
	 * 获取一个list的长度
	 * @param key
	 * @return
	 */
	public Long getListLen(String key) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getListLen current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getListLen current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		return shardedJedis.llen(key);
	}

	/**
	 * 清除list，只保留beginIndex和endIndex之间的内容
	 * 
	 * @param key
	 * @param beginIndex
	 * @param endIndex
	 * @return
	 */
	public String trimList(String key, long beginIndex, long endIndex) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in trimList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in trimList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		return shardedJedis.ltrim(key, beginIndex, endIndex);
	}

	/**
	 * 对数字的value增加
	 * 
	 * @param key
	 * @param num
	 * @return
	 */
	public Long incrBy(String key, long num) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in incrBy current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in incrBy current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		return shardedJedis.incrBy(key, num);
	}

	/**
	 * 对数字的value减少
	 * 
	 * @param key
	 * @param num
	 * @return
	 */
	public Long decrBy(String key, long num) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in decrBy current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in decrBy current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		return shardedJedis.decrBy(key, num);
	}

	/**
	 * 将序列化对象插入缓存，暂不支持中文key（可能会有编码问题）
	 * 
	 * @param key
	 * @param obj
	 * @return
	 */
	public String setSingleObject(String key, Object obj) {
		if (null == obj)
			return null;
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in setSingleObject current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in setSingleObject current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setExcludes(new String[] { "" });
		jsonConfig.setIgnoreDefaultExcludes(false);
		jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
		jsonConfig.registerJsonValueProcessor(Date.class,        
				new JsonDateValueProcessor("yyyy-MM-dd HH:mm:ss"));
		String json = JSONArray.fromObject(obj, jsonConfig).toString();
		json = json.substring(1, json.length()-1);
		return this.setSingleString(key, json);
	}

	/**
	 * 获取对象，暂不支持中文key（可能会有编码问题）
	 * 
	 * @param key
	 * @return
	 */
	public Object getSingleObject(String key) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getsingleobject current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getsingleobject current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		JSONArray json = JSONArray.fromObject(this.getSingleString(key));
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] { "yyyy-MM-dd HH:mm:ss" }));
		return JSONArray.toArray(json);
	}
	
	/**
	 * 获取对象，暂不支持中文key（可能会有编码问题）
	 * 
	 * @param key
	 * @param clazz
	 * @return
	 */
	public Object getSingleObject(String key, Class<?> clazz) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getsingleobject current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getsingleobject current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		String singleString = this.getSingleString(key);
		if(singleString == null)
			return null;
		if(singleString.substring(0,1).equals("[") && singleString.substring(singleString.length()-1, singleString.length()).equals("]"))
			singleString = singleString.substring(1, singleString.length()-1);
		
		//singleString = singleString.substring(1, singleString.length()-1);
		JSONObject json = JSONObject.fromObject(singleString);
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] { "yyyy-MM-dd HH:mm:ss" }));
		return JSONObject.toBean(json, clazz);
	}
	
	/**
	 * 获取对象，暂不支持中文key（可能会有编码问题）
	 * 
	 * @param key
	 * @param clazz
	 * @return
	 */
	public Object getSingleObject(String key, Class<?> clazz, ClassMap classMap) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getsingleobject current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getsingleobject current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		String singleString = this.getSingleString(key);
		if(singleString == null)
			return null;
		//singleString = singleString.substring(1, singleString.length()-1);
		JSONObject jsonObject = JSONObject.fromObject(singleString);
		JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpher(new String[] { "yyyy-MM-dd HH:mm:ss" }));
		return JSONObject.toBean(jsonObject, clazz, classMap);
	}

	/**
	 * 删除一个key
	 * 
	 * @param key
	 * @return
	 */
	public Long delKey(String key) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in delkey current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in delkey current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		return shardedJedis.del(key);
	}
	
	/**
	 * 删除多个个keys
	 * @param keys
	 * @return
	 */
	public Long delKey(String... keys) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		Collection<Jedis> jedisCollection = shardedJedis.getAllShards();
		Iterator<Jedis> jedisIterator= jedisCollection.iterator();
		Long res = 0L;
		while(jedisIterator.hasNext()) {
			Jedis jedis = jedisIterator.next();
			res =+ jedis.del(keys);
		}
		return res;
	}
	
	/**
	 * 批量获取key-value
	 * @param keys
	 * @return
	 */
	public Map<String, JSONArray> batchGetMap(String... keys) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		ShardedJedisPipeline shardedJedisPipeline = shardedJedis.pipelined();
		Map<String, JSONArray> maps = new HashMap<String, JSONArray>();
		List<Response<?>> responses = new ArrayList<Response<?>>();
		for(String key : keys) {
			responses.add(shardedJedisPipeline.get(key));
		}
		shardedJedisPipeline.sync();
		for(int i=0; i<keys.length; i++) {
			JSONArray json = JSONArray.fromObject(responses.get(i).get());
			maps.put(keys[i], json);
		}
		return maps;
	}
	
	/**
	 * <b>模糊查询所有匹配的key</b><br/>
	 * key模糊规则如下:<br/>
	 * key="*string"查询以string结尾的key<br/>
	 * key="string*"查询以string开头的key<br/>
	 * key="*string*"查询存在string的key<br/>
	 * key="string*string"查询以string为开头和结尾的key<br/>
	 * @param key
	 * @return List<String> keys
	 */
	public List<String> getKeys(String key) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		Collection<Jedis> jedisCollection = shardedJedis.getAllShards();
		Iterator<Jedis> jedisIterator= jedisCollection.iterator();
		List<String> res = new ArrayList<String>();
		while(jedisIterator.hasNext()) {
			Jedis jedis = jedisIterator.next();
			Iterator<String> keys = jedis.keys(key).iterator();
			while(keys.hasNext()) {
				res.add(keys.next());
			}
		}
		return res;
	}
  
	public Map<String,String> getKeysByRang(String listKey, int count) {
      ShardedJedis shardedJedis= getCurShardedJedis();
      
      Collection<Jedis> jedisCollection = shardedJedis.getAllShards();
      Iterator<Jedis> jedisIterator= jedisCollection.iterator();
      Map<String,String> res = new HashMap<String,String>();
      Jedis jedis = jedisIterator.next();
      for(int i=0; i<count; i++){
        String key = jedis.randomKey();
        logger.debug("key"+key);
       // if ("string".equals(jedis.type(key))) {
          if (!listKey.equals(key)) {
            try {
              res.put(key,jedis.get(key));
            } catch (Exception e) {
              logger.error(key+"不是string类型"+e.getMessage(),e);
              continue;
            }
          }
       // }
        
       
      }
      return res;
      
  }
	
	public List<String> getListFromProducer(String key, int count) {
		ShardedJedis shardedJedis= getCurShardedJedis();
		ShardedJedisPipeline  shardedJedPipeline=shardedJedis.pipelined();
		Response<List<String>> respStr=shardedJedPipeline.lrange(key, 0, count);
		shardedJedPipeline.ltrim(key, count+1, -1);
		shardedJedPipeline.sync();
		return respStr.get();
	}

	public Long setStringToList(String key, List<String> list, long where) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in setStringToList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in setStringToList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		if (0 == where) {
			Long res = shardedJedis.lpush(key, list.toArray(new String[list.size()]));
			return res;
		} else {
			Long res = shardedJedis.rpush(key, list.toArray(new String[list.size()]));
			return res;
		}
	}

	public String setStringAndList(String key, String listKeyString,
			String value, long where) {
		ShardedJedis shardedJedis= getCurShardedJedis();
		ShardedJedisPipeline  shardedJedPipeline=shardedJedis.pipelined();
		shardedJedPipeline.rpush(listKeyString, value);
		Response<String> res = shardedJedPipeline.set(key, value);
		shardedJedPipeline.sync();
		return res.get();
	}
	
	public List<String> getListBykeys(String... keys) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		ShardedJedisPipeline shardedJedisPipeline = shardedJedis.pipelined();
		List<String> list = new ArrayList<String>();
		List<Response<String>> responses = new ArrayList<Response<String>>();
		for(String key : keys) {
			responses.add(shardedJedisPipeline.get(key));
		}
		shardedJedisPipeline.sync();
		for(int i=0; i<keys.length; i++) {
			list.add(responses.get(i).get());
		}
		return list;
	}
	/**
	 * json对象转换
	 * @param obj
	 * @return
	 */
	private String converObjectToJason(Object obj){
		try{
			JsonConfig jsonConfig = new JsonConfig();
			jsonConfig.setExcludes(new String[] { "" });
			jsonConfig.setIgnoreDefaultExcludes(false);
			jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
			jsonConfig.registerJsonValueProcessor(Date.class,        
					new JsonDateValueProcessor("yyyy-MM-dd HH:mm:ss"));
		
			String json = JSONArray.fromObject(obj, jsonConfig).toString();
			json = json.substring(1, json.length()-1);
			return json;
		}catch(Exception e){
			logger.error("converObjectToJason error:" + e);
			return null;
		}
		
	}
	public Long remAndSetStringToList(String keyToRem, String strToRem,
			String keyToSet, Object objToSet, int where) {
		String json = converObjectToJason(objToSet);
		if(null == json)
			return null;
		ShardedJedis shardedJedis= getCurShardedJedis();
		ShardedJedisPipeline  shardedJedPipeline=shardedJedis.pipelined();
		shardedJedPipeline.lrem(keyToRem, 0, strToRem);
		Response<Long> res;
		if (0 == where) {
			res = shardedJedPipeline.lpush(keyToSet, json);
		} else {
			res = shardedJedPipeline.rpush(keyToSet, json);
		}
		shardedJedPipeline.sync();
		if(null == res) return null;
		return res.get();
	}

	public Long addObjectAndStringToList(String objKey, Object obj,
			String key1, String keyValue1, String key2, String keyValue2,int where) {
		return null;
	}

	public Long remObjectAndStringToList(String key, String keyValue,
			String key1, String keyValue1, String key2, String keyValue2) {
		ShardedJedis shardedJedis= getCurShardedJedis();
		ShardedJedisPipeline  shardedJedPipeline=shardedJedis.pipelined();
		Response<Long> res;
		shardedJedPipeline.lrem(key, 0, keyValue);
		shardedJedPipeline.lrem(key1, 0, keyValue1);
		res=shardedJedPipeline.lrem(key2, 0, keyValue2);
		shardedJedPipeline.sync();
		if(null == res) return null;
		return res.get();
	}
	
	public Long setExpire(String key) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in setStringToList current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		Long res=0L;
		return res;
	}
	
	public Long removeLrem(String key, long count,String value) {
		ShardedJedis shardedJedis = getCurShardedJedis();
		logger.debug("in getsingleobject current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "]");
		logger.debug("in getsingleobject current server is:["
				+ shardedJedis.getShard(key).getClient().getHost() + "],key is:["+key+"]");
		return shardedJedis.lrem(key,0, value);
	}
	
	public List<Object> rpushListAndSetKey(String listKey,
			List<String> listValue, Map<String, String> stringMap) throws Exception {
		// TODO Auto-generated method stub
		ShardedJedis shardedJedis=getCurShardedJedis();
		List<Object> resultList=new ArrayList<Object>();
		try{
			ShardedJedisPipeline shardeJedisPipeline=shardedJedis.pipelined();//redis管道，批量执行命令
			for(String key:stringMap.keySet()){
				try{
					shardeJedisPipeline.set(key,stringMap.get(key));
				}catch (Exception e) {
					// TODO: handle exception
					logger.error(key+",set异常==="+e.getMessage(), e);
					throw e;
				}
			}
			for(String value:listValue){
				try{
					shardeJedisPipeline.rpush(listKey, value);
				}catch (Exception e) {
					// TODO: handle exception
					logger.error(value+",rpush异常==="+e.getMessage(),e);
				}
			}
			resultList=shardeJedisPipeline.syncAndReturnAll();
		}catch (Exception e) {
			throw e;
		}
		return resultList;
	}

	public List<Object> rpushListAndSetKey(String listKey, String key,
			String value) throws Exception {
		return null;
	}

	public List<String> getServiceObjectRemoveList(List<String> listkey,
			int size) throws Exception {
		return null;
	}

	public Long rpushListValue(String listKey, String value) throws Exception {
		return null;
	}
	
}
